//
//  MainViewController.m
//  smart_transferor
//
//  Created by Cherry on 11-11-1.
//  Copyright (c) 2011年 __MyCompanyName__. All rights reserved.
//

#import "MainViewController.h"
#import "WifiTransferor.h"
#import "STFileItem.h"
#import "FileMetaInfo.h"
#import "iToast.h"

@interface MainViewController()
{
@private
    enum MainViewState{
        MainViewStateDefault,
        MainViewStateSelectingFile,
        MainViewStateReadyToSend,
        MainViewStateReadyToReceive
    };
    
    enum MainViewState viewState;
    bool isAnimationRunning;
    CGPoint originalCenter; 
    UIPanGestureRecognizer *panGestureRecognizer;
    id<Transferor> transferor;
    STFileItem *currentFileItem;
    
    NSMutableDictionary *sendingMap;
    NSMutableDictionary *receivingMap;
    NSMutableArray *waitingRecArray;
}

- (void)initAnimationItems;
- (void)prepareForSendingFile;
- (void)finishedSendingFile; 
- (void)startReceivedAnimation;
- (void)stopReceivedAnimation;
- (void)changeViewState:(enum MainViewState)newState;
- (void)handleSendFile:(STFileItem *)file;
- (void)handleReivingFile;
@end




@implementation MainViewController

@synthesize fileItem;
@synthesize fileSelectViewController;
@synthesize cancelSendFileButton;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        transferor = [[WifiTransferor alloc] init];
        [transferor setCallback:self];
        sendingMap = [[NSMutableDictionary alloc] init];
        receivingMap = [[NSMutableDictionary alloc] init];
        waitingRecArray = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - Delegate STFileScreenDelegate

- (void)selectFile:(STFileItem *)file FromFileView:(STFileViewController *)fileview
{
    NSLog(@"select file");
    NSAssert(viewState = MainViewStateSelectingFile, nil);
    
    [self changeViewState:MainViewStateReadyToSend];
    isAnimationRunning = true;
    
    if (currentFileItem != nil)
    {
        [currentFileItem release];
    }
    currentFileItem = file;
    [currentFileItem retain];
    
    cancelSendFileButton.alpha = 1;
    
    [self prepareForSendingFile];
    
    [self dismissViewControllerAnimated:YES completion:^{
        isAnimationRunning = false;
    }];
}

- (void)quitWithoutSelectionFromFileView:(STFileViewController *)fileview
{
    NSLog(@"cancel Test");
    NSAssert(viewState = MainViewStateSelectingFile, nil);
        
    [self changeViewState:MainViewStateReadyToSend];
    isAnimationRunning = true;
    
    [self dismissViewControllerAnimated:YES completion:^{
        isAnimationRunning =false;
    }];
}

#pragma mark - Delegate UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if ([waitingRecArray count] != 0)
    {
        id key = [waitingRecArray objectAtIndex:0];
        int recvId = [((NSNumber *) key) intValue];
        
        if (buttonIndex == 0)
        {
            [transferor actionForRecv:recvId accept:NO];
            [waitingRecArray removeObjectAtIndex:0];
            [receivingMap removeObjectForKey:key];
        }
        else
        {
            [transferor actionForRecv:recvId accept:YES];
            [waitingRecArray removeObjectAtIndex:0];
        }
    }
    
    
    [UIView animateWithDuration:0.3 delay:0.2 options:UIViewAnimationOptionCurveEaseIn animations:^{
        fileItem.alpha = 0;
    } completion:^(BOOL b){
        [self changeViewState:MainViewStateDefault];
    }];
}

#pragma mark - Delegate TransferorCallback

- (void)didSendFinished:(int) sendId
{
    NSLog(@"Finish sending: %d", sendId);
    id value = [sendingMap objectForKey:[NSNumber numberWithInt:sendId]];
    if (value != nil)
    {
        [sendingMap removeObjectForKey:[NSNumber numberWithInt:sendId]];
        [[iToast makeText:@"File Finish Sending."] show];
    }
    else
    {
        NSLog(@"No such send Id");
        NSAssert(false, @"No such send Id");
    }
}

- (void)newFileComing:(FileMetaInfo *)file identity:(int)recvid
{
    NSLog(@"New file comming: %@, %d", file, recvid);

    id value = [receivingMap objectForKey:[NSNumber numberWithInt:recvid]];
    if (value == nil)
    {
        NSNumber *key = [NSNumber numberWithInt:recvid];
        [receivingMap setObject:file forKey:key];
        [waitingRecArray addObject:key];
        
        [self handleReivingFile];
    }
    else
    {
        NSLog(@"duplicate recvid");
        NSAssert(false, @"duplicate recvid");
    }
}

- (void)didRecvFinished:(int)recvid
{
    NSLog(@"received Finished: %d", recvid);
    
    id value = [receivingMap objectForKey:[NSNumber numberWithInt:recvid]];
    if (value != nil)
    {
        FileMetaInfo *fileMetaInfo = [receivingMap objectForKey:[NSNumber numberWithInt:recvid]];
        if (fileMetaInfo != nil)
        {
            NSString *fileAbsPath = [fileMetaInfo filePath];
            NSLog(@"insert a new file to model:%@",fileAbsPath);
            int index = [fileAbsPath length] - 1;
            unichar c = [fileAbsPath characterAtIndex:index];
            while(c != '/')
            {
                index--;
                if (index >=0)
                {
                    c = [fileAbsPath characterAtIndex:index];
                }
            }
            if (index <= 0)
            {
                NSLog(@"the filePath is not right");
            }
            NSString *fileName = [fileAbsPath substringFromIndex:index + 1];
            NSString *filePath = [fileAbsPath substringToIndex:index];
            STFileItem *newFileItem = [[STFileItem alloc]initWithFileName:fileName AndDir:filePath];
            [fileSelectViewController insertItem:newFileItem];
            [newFileItem release]; 
            [receivingMap removeObjectForKey:[NSNumber numberWithInt:recvid]];
            [[iToast makeText:@"File Received."] show];
            
        }
        else
        {
            NSLog(@"No such recvid");
            NSAssert(false, @"No such recvid");
        }
    }
    else
    {
        NSLog(@"No such recv Id");
        NSAssert(false, @"No such recv Id");
    }
}

- (void)notify:(NotifyCode)code :(int)param1 :(int)param2
{
    NSLog(@"Received Notify: %d, %d", param1, param2);
}


#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    cancelSendFileButton.alpha = 0;
    [self initAnimationItems];
    [self changeViewState:MainViewStateDefault];
    [transferor startListen];
}

- (void)viewDidUnload
{
    [self setCancelSendFileButton:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.fileItem = nil;
    self.fileSelectViewController = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)dealloc {
    [panGestureRecognizer release];
    [fileItem release];
    [fileSelectViewController release];
    [transferor release];
    if (currentFileItem != nil)
    {
        [currentFileItem release];
    }
    [sendingMap release];
    [receivingMap release];
    [waitingRecArray release];
    [cancelSendFileButton release];
    [super dealloc];
}

#pragma mark - UI Operation

- (IBAction)goToFileSelectionView:(id)sender {
    
    NSAssert(viewState == MainViewStateDefault || viewState == MainViewStateReadyToSend ,nil);
    
    [self changeViewState:MainViewStateSelectingFile];
    isAnimationRunning = true;
    
    [self presentViewController:self.fileSelectViewController
                       animated:YES
                     completion:^{
                         NSAssert(viewState == MainViewStateSelectingFile, nil);
                         isAnimationRunning = false;
                     }];
}

- (IBAction)cancelCurrentFile:(id)sender {
    [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        fileItem.alpha = 0;
        cancelSendFileButton.alpha = 0;
    } completion:^(BOOL b){
        [self finishedSendingFile];
    }];
}

- (IBAction)receivedNewFile:(id)sender {
    // TODO: Delete later, for test now.
    // [self handleReivingFile];
}

- (IBAction)handlePanGestrue:(UIPanGestureRecognizer *)panGR
{
    NSLog(@"%d",panGR.state);
    UIView *focusView = [panGR view];
    UIView *parentView = [focusView superview];
    CGPoint delta = [panGR translationInView:parentView];
    
    switch (panGR.state) {
        case UIGestureRecognizerStateBegan:
        case UIGestureRecognizerStateChanged:
            {
                if (delta.y < 0)
                {
                    
                    CGPoint newPosition = CGPointMake(originalCenter.x , originalCenter.y +delta.y);
                    fileItem.center = newPosition;
                }
                else
                {
                    fileItem.center = originalCenter;
                }
            }
            break;
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateFailed:
        case UIGestureRecognizerStateCancelled:
            {
                if (originalCenter.y + delta.y <= 50)
                {
                    CGPoint v = [panGR velocityInView:parentView];
                    float t = (-300.0 - (originalCenter.y + delta.y)) / v.y;
                    if (t >= 0.5) t = 0.5;
                    
                    [UIView animateWithDuration:t delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
                        fileItem.center = CGPointMake(originalCenter.x, -300);
                        cancelSendFileButton.alpha = 0.0;
                    } completion:^(BOOL finished) {
                        [self finishedSendingFile];
                    }];
                    
                    [self handleSendFile:currentFileItem];
                    
                }
                else
                {
                    [UIView beginAnimations:nil context:nil];
                    fileItem.center = originalCenter;
                    [UIView commitAnimations];
                }
            }
            break;
        default:
            break;
    }
    
}

- (void)prepareForSendingFile {
    fileItem.alpha = 1.0;
    fileItem.center = originalCenter;
    [fileItem addGestureRecognizer:panGestureRecognizer];
}

- (void)finishedSendingFile {
    [fileItem removeGestureRecognizer:panGestureRecognizer];
}

- (void)startReceivedAnimation {
    fileItem.center = CGPointMake(originalCenter.x, -300);
    fileItem.alpha = 1.0;
    
    [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        fileItem.center = originalCenter;
    } completion:^(BOOL finished) {
        isAnimationRunning = false;
    }];
}

- (void)stopReceivedAnimation {
    
}

- (void)changeViewState:(enum MainViewState)newState
{
    NSLog(@"Change to State : <%d> -> <%d>", viewState, newState);
    viewState = newState;
}

- (void)initAnimationItems
{
    originalCenter = fileItem.center;
    
    panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGestrue:)];
    panGestureRecognizer.maximumNumberOfTouches = 1;
    panGestureRecognizer.minimumNumberOfTouches = 1;
    
    fileItem.alpha = 0;
}

- (void)handleSendFile:(STFileItem *)file
{
    FileMetaInfo *metaInfo = [[FileMetaInfo alloc] init];
    metaInfo.filePath = file.absPath;
    metaInfo.length = [[[[NSFileManager defaultManager] attributesOfItemAtPath:file.absPath error:nil] objectForKey:NSFileSize] intValue];
    
    switch (file.fileType)
    {
        case kImage:
            metaInfo.type = kFileTypeImage;
            break;
        case kAudio:
            metaInfo.type = kFileTypeAudio;
            break;
        case kVideo:
            metaInfo.type = kFileTypeVideo;
            break;
        case kMovie:
            metaInfo.type = kFileTypeMovie;
            break;
        case kDirectory:
            metaInfo.type = kFileTypeDirectory;
            break;
        case kOther:
        default:
            metaInfo.type = kFileTypeOther;
            break;
    }
    
    int sendMsgId = [transferor send:metaInfo];
    
    [sendingMap setObject:file forKey:[NSNumber numberWithInt:sendMsgId]];
    
    [metaInfo release];
}

- (void)handleReivingFile
{        
    [self changeViewState:MainViewStateReadyToReceive];
    isAnimationRunning = true;

    fileItem.center = CGPointMake(originalCenter.x, -300);
    fileItem.alpha = 1.0;
    
    [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        fileItem.center = originalCenter;
    } completion:^(BOOL finished) {
        isAnimationRunning = false;
        
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"File Received" 
                                                            message:@"Do you want to received this file?" 
                                                           delegate:self 
                                                  cancelButtonTitle:@"No" 
                                                  otherButtonTitles:@"Yes", nil];
        
        [alertView show];
        [alertView release];
    }];

}


@end
